/*
 *
 */

#include "gkt_types.h"

#ifndef BB_PROTOCOL_H
#define BB_PROTOCOL_H

/* network layer */
#ifdef GKT_CONFIG_BB_NETWORK_PACKET_MAXLEN
#define BB_NETWORK_PACKET_MAXLEN	\
	GKT_CONFIG_BB_NETWORK_PACKET_MAXLEN
#else
#define BB_NETWORK_PACKET_MAXLEN	64
#endif

#define BB_NETWORK_PREAMBLE_SIZE	3
#define BB_NETWORK_LENGTH_SIZE	1
#define BB_NETWORK_CRC_SIZE	1

#define BB_NETWORK_PREAMBLE_OFFSET	0
#define BB_NETWORK_LENGTH_OFFSET	\
	(BB_NETWORK_PREAMBLE_OFFSET + BB_NETWORK_PREAMBLE_SIZE)
#define BB_NETWORK_PAYLOAD_OFFSET	\
	(BB_NETWORK_LENGTH_OFFSET + BB_NETWORK_LENGTH_SIZE)

#define BB_NETWORK_PAYLOAD_MAXSIZE	\
	(BB_NETWORK_PACKET_MAXLEN - BB_NETWORK_PAYLOAD_OFFSET \
		- BB_NETWORK_CRC_SIZE)

#define BB_NETWORK_PACKET_SIZE(net_payload_size)	\
	(BB_NETWORK_PAYLOAD_OFFSET + (net_payload_size) + BB_NETWORK_CRC_SIZE)

#define BB_NETWORK_PREAMBLE	0x474250

/* transport layer */
#define BB_TRANSPORT_CTL_SI_SIZE	1
#define BB_TRANSPORT_TRANSID_SIZE	1

#define BB_TRANSPORT_CTL_SI_OFFSET	0
#define BB_TRANSPORT_TRANSID_OFFSET	\
	(BB_TRANSPORT_CTL_SI_OFFSET + BB_TRANSPORT_CTL_SI_SIZE)
#define BB_TRANSPORT_PAYLOAD_OFFSET	\
	(BB_TRANSPORT_TRANSID_OFFSET + BB_TRANSPORT_TRANSID_SIZE)

#define BB_TRANSPORT_PAYLOAD_MAXSIZE	\
	(BB_NETWORK_PAYLOAD_MAXSIZE - BB_TRANSPORT_PAYLOAD_OFFSET)

#define BB_TRANSPORT_PACKET_OFFSET	BB_NETWORK_PAYLOAD_OFFSET
#define BB_TRANSPORT_PACKET_SIZE(trans_payload_size)	\
	BB_NETWORK_PACKET_SIZE(BB_TRANSPORT_PAYLOAD_OFFSET + (trans_payload_size))

#define BB_TRANSPORT_CTL_BITS	2
#define BB_TRANSPORT_LSI_BITS	3
#define BB_TRANSPORT_CSI_BITS	3
#define BB_TRANSPORT_SEG_MAXNUMS	(1U << BB_TRANSPORT_LSI_BITS)

#define BB_TRANSPORT_CTL_SHIFT	0
#define BB_TRANSPORT_LSI_SHIFT	\
	(BB_TRANSPORT_CTL_SHIFT + BB_TRANSPORT_CTL_BITS)
#define BB_TRANSPORT_CSI_SHIFT	\
	(BB_TRANSPORT_LSI_SHIFT + BB_TRANSPORT_LSI_BITS)

#define BB_TRANSPORT_CTL_MASK	\
	gkt_mask(BB_TRANSPORT_CTL_BITS, BB_TRANSPORT_CTL_SHIFT)
#define BB_TRANSPORT_LSI_MASK	\
	gkt_mask(BB_TRANSPORT_LSI_BITS, BB_TRANSPORT_LSI_SHIFT)
#define BB_TRANSPORT_CSI_MASK	\
	gkt_mask(BB_TRANSPORT_CSI_BITS, BB_TRANSPORT_CSI_SHIFT)

#define BB_TRANSPORT_ITEM(NAME, value)	\
	(((value) >> BB_TRANSPORT_##NAME##_SHIFT) & BB_TRANSPORT_##NAME##_MASK)

/* application layer */
#define BB_APPLICATION_MODULE_ID_SIZE	1
#define BB_APPLICATION_OPCODE_SIZE	1

#define BB_APPLICATION_MODULE_ID_OFFSET	0
#define BB_APPLICATION_OPCODE_OFFSET	\
	(BB_APPLICATION_MODULE_ID_OFFSET + BB_APPLICATION_MODULE_ID_SIZE)
#define BB_APPLICATION_DATA_OFFSET	\
	(BB_APPLICATION_OPCODE_OFFSET + BB_APPLICATION_OPCODE_SIZE)

#define BB_APPLICATION_MAXSIZE	\
	(BB_TRANSPORT_PAYLOAD_MAXSIZE * BB_TRANSPORT_SEG_MAXNUMS)

#define BB_APPLICATION_PACKET_SIZE(data_size)	\
	BB_TRANSPORT_PACKET_SIZE(BB_APPLICATION_DATA_OFFSET + data_size)

/* total packet minsize */
#define GKT_PACKET_MINSIZE	\
	(BB_NETWORK_PAYLOAD_OFFSET + BB_TRANSPORT_PAYLOAD_OFFSET \
		+ 1 + BB_NETWORK_CRC_SIZE)

/* network layer */
int bb_network_init(void);
int bb_network_send_packet(uint8_t *payload_buff, uint32_t length);
void bb_network_packet_received(const uint8_t *data, uint32_t length);

/* transport layer */
int bb_transport_init(void);
int bb_transport_send_data(const uint8_t *data, uint32_t length);
void bb_transport_packet_received(const uint8_t *packet, uint32_t length);
void bb_transport_send_heartbeat(void);

/* application layer */
void bb_application_packet_received(const uint8_t *data, uint32_t length);


#endif	/* BB_PROTOCOL_H */

